<?php

declare(strict_types=1);

namespace Service\CommodityService;

use Service\BaseService;
use Service\Code\Normal;
use Service\ConsumerService\ConsumerMapping\CommodityMapping;
use Service\SupplierService\SupplierService;

class SupplierCommodityConsumerService extends BaseService
{
    const UNIQUE_KEY = 'SupplierCommoditySkuCode';
    const VALIDATE_TYPE = 'supplier_pull_message';

    /**
     * 供应商商品消费
     * @param $message
     * @return array
     */
    public function consumer($message): array
    {
            //获取供应商信息
            $supplier = SupplierService::instance()->getConsumerSupplierInfo($message['SupplierID']);
            //最后一页只下架商品
            if ($message['IsLastPage'] == 1) {
                //部分供应商不支持批量下架 所以这里需要判断
                if ($supplier['CommodityIsBatchDown'] == 1) {
                    return SupplierCommodityService::instance()->batchCommodityDown($supplier['SupplierID'], 1);
                }
                return Normal::returnSuccessCode();
            }

            //第一页数据,需要将供应商商品全部置为待下架状态
            if ($message['IsFirstPage']) {
                SupplierCommodityService::instance()->changeCommodityDownStatus($supplier['SupplierID']);
            }

            //获取供应商映射类
            $MappingResult = SupplierService::instance()->getSupplierMapping($supplier);
    
            //获取映射失败
            if ($MappingResult['code'] != Normal::SUC) {
                return Normal::returnCode($MappingResult['code'], $MappingResult['msg']);
            }
            $SupplierMapping = ($MappingResult['data'])::instance();

            //获取需要批量处理的前置数据(旧数据,Hscodes)
            $supplierSkuCodes = $SupplierMapping->getGoodsSkus($message['GoodsItemList']);
            if (empty($supplierSkuCodes)) {
                return Normal::returnSuccessCode();
            }
            $ConsumerDataMappings = SupplierCommodityService::instance()->getPreConsumerData($supplierSkuCodes, $supplier);
            $pendingItems = [];
            //循环处理供应商数据
            foreach ($message['GoodsItemList'] as $supplierGoods) {
                //获取映射数据
                $goodsMapping = $SupplierMapping->getGoodsMapping($supplierGoods, $ConsumerDataMappings['HsCodeMapping'], $supplier);
                if (!$goodsMapping) {
                    continue;
                }
                $uniqueKey = $goodsMapping['base'][self::UNIQUE_KEY];
                //判断是否存在老的数据
                if (isset($ConsumerDataMappings['goodsMapping'][$uniqueKey])) {
                    //处理老数据
                    $pendingItems[] = $this->handleAlreadyGoods($goodsMapping, $ConsumerDataMappings, $uniqueKey);
                } else {
                    //处理新数据
                    if ($supplier['SyncMode'] == 0) {
                        $pendingItems[] = $this->getPendingItem($goodsMapping, [], 'insert', true);
                    }
                }
            }
            //这边需要获取需要修改主资料数据
            $isChangeArchivesPendingItems = array_map(function ($item) {
                if ($item['isChangeArchives']) {
                    return $item;
                }
                return [];
            }, $pendingItems);

            $changeArchivesCondition = array_column($isChangeArchivesPendingItems,  'goodsMapping');
            $matchArchives = CommodityArchivesService::instance()->getConsumerMatchItem($changeArchivesCondition);
            //批量处理数据
            $batchResult = $this->batchProcessItems($pendingItems, $matchArchives, $supplier);

            //修改状态,已修改的商品
            SupplierCommodityService::instance()->ChangeGoodsUp($batchResult['data']['ChangeGoodsUpIDs']);

            //推送数据 todo
            //        if (!empty($needPush['SupplierCommodityIDList'])){
            //            $pusher=new SupplierCommodityChange();
            //            $pusher->publish($needPush);
            //        }
            return Normal::returnCode(Normal::SUC, "处理成功");
    }

    /**
     * 处理已存在的商品数据
     * @param $goodsMapping
     * @param $ConsumerDataMappings
     * @param $uniqueKey
     * @return array
     */
    public function handleAlreadyGoods($goodsMapping, $ConsumerDataMappings, $uniqueKey): array
    {
        //初始化数据
        $goodsMapping['base'] = $this->initBaseGoodsMapping(
            $goodsMapping,
            $ConsumerDataMappings['goodsMapping'][$uniqueKey]
        );
        //验证商品数据是否变化
        $CommodityChange = SupplierCommodityValidateService::instance()->checkCommodityArchivesChange([
            'goodsBaseMapping' => $goodsMapping['base'],
            'oldGoodsBaseMapping' => $ConsumerDataMappings['goodsMapping'][$uniqueKey]
        ]);
        return $this->getPendingItem(
            $goodsMapping,
            [
                'base' => $ConsumerDataMappings['goodsMapping'][$uniqueKey],
                'stock' => $ConsumerDataMappings['stockMapping'][$uniqueKey] ?? [],
                'custom' => $ConsumerDataMappings['stockMapping'][$uniqueKey] ?? []
            ],
            'update',
            $CommodityChange
        );
    }

    /**
     * 填写商品数据默认值
     * @param $goodsBase
     * @param $oldGoodsBase
     * @return array
     */
    private function initBaseGoodsMapping($goodsMapping, $oldGoodsBase): array
    {
        //填入默认的主资料id
        $archivesKey = CommodityMapping::instance()->commodityArchivesID;
        $goodsMapping['base'][$archivesKey] = $oldGoodsBase[$archivesKey];
        //判断是否有需要默认填入的字段
        if (empty($goodsMapping['update_hidden'])) {
            return $goodsMapping['base'];
        }
        //填入默认字段
        foreach ($goodsMapping['update_hidden'] as $key => $value) {
            $goodsMapping['base'][$key] = $oldGoodsBase[$key];
        }
        return $goodsMapping['base'];
    }

    /**
     * 获取等待处理的数据
     * @param $goodsMapping
     * @param $oldGoodsMapping
     * @param $changeType
     * @param $isChangeArchives
     * @return array
     */
    private function getPendingItem($goodsMapping, $oldGoodsMapping, $changeType, $isChangeArchives): array
    {
        return [
            'goodsMapping' => $goodsMapping,
            'oldGoodsMapping' => $oldGoodsMapping,
            'changeType' => $changeType,
            'isChangeArchives' => $isChangeArchives
        ];
    }

    /**
     * 批量处理商品数据
     * @param array $pendingItems
     * @param array $matchArchives
     * @param array $supplierInfo
     * @return array
     */
    private function batchProcessItems(array $pendingItems, array $matchArchives, array $supplierInfo)
    {
        $ChangeGoodsUpIDs = $toPushIDs = [];
        foreach ($pendingItems as $pendingItem) {
            //判断是否需要更新主资料(变动过部分数据需要更新主资料)
            if ($pendingItem['isChangeArchives']) {
                $matchArchiveResult = CommodityArchivesService::instance()->matchArchive($pendingItem['goodsMapping'], $matchArchives, $supplierInfo);
                $pendingItem['goodsMapping']['base'] = $matchArchiveResult['base'];
            }
            //判断业务是否为新增商品或者修改商品
            if ($pendingItem['changeType'] == 'insert') {
                $ProcessingResult = SupplierCommodityService::instance()->insertConsumerCommodity($pendingItem, $supplierInfo);
            } else {
                $ProcessingResult = SupplierCommodityService::instance()->updateConsumerCommodity($pendingItem, $supplierInfo, self::VALIDATE_TYPE);
            }
            if ($ProcessingResult['code'] != Normal::FAIL) {
                return $ProcessingResult;
            }
            $ChangeGoodsUpIDs[] = $ProcessingResult['data']['ID'];
            if ($ProcessingResult['data']['toPush'] == 1) {
                $toPushIDs[] = $ProcessingResult['data']['ID'];
            }
        }
        return Normal::returnCode(Normal::SUC, "处理成功", ['changeGoodsUpIDs' => $ChangeGoodsUpIDs, 'toPushIDs' => $toPushIDs]);
    }
}
